#include <string>
#include "zmq.hpp"
#include "json.h"

using namespace std;

void send_command(zmq::socket_t&, string); // From IO_Functions.cpp
void wait_for_response(zmq::socket_t&); // From IO_Functions.cpp
string determine_our_tank_id(json::Object, string); // From Tank_Info.cpp

void our_fast_tank_move(zmq::socket_t& command_channel, json::Object game_state, string client_token,double distance)
{
	// Initialize variables
	string our_fast_tank_id;
	string direction;

	// Determine our fast tank id
	our_fast_tank_id = determine_our_tank_id(game_state, "TankFast");

	// Determine direction
	if (distance > 0)
	{
		direction = "FWD";
	}
	else
	{
		direction = "REV";
		distance = distance * -1;
	}

	// Build a JSON command message
	json::Object obj; // Create a data container
	obj["tank_id"] = our_fast_tank_id;
	obj["comm_type"] = "MOVE";
	obj["direction"] = direction;
	obj["distance"] = distance;
	obj["client_token"] = client_token;
	string str = json::Serialize(obj); // Turn the container into a string

	// Send command
	send_command(command_channel, str);
	wait_for_response(command_channel);
}

void our_slow_tank_move(zmq::socket_t& command_channel, json::Object game_state, string client_token,double distance)
{
	// Initialize variables
	string our_slow_tank_id;
	string direction;

	// Determine our slow tank id
	our_slow_tank_id = determine_our_tank_id(game_state, "TankSlow");

	// Determine direction
	if (distance > 0)
	{
		direction = "FWD";
	}
	else
	{
		direction = "REV";
		distance = distance * -1;
	}

	// Build a JSON command message
	json::Object obj; // Create a data container
	obj["tank_id"] = our_slow_tank_id;
	obj["comm_type"] = "MOVE";
	obj["direction"] = direction;
	obj["distance"] = distance;
	obj["client_token"] = client_token;
	string str = json::Serialize(obj); // Turn the container into a string

	// Send command
	send_command(command_channel, str);
	wait_for_response(command_channel);
}

void our_fast_tank_rotate(zmq::socket_t& command_channel, json::Object game_state, string client_token, double degrees)
{
	// Initialize variables
	string our_fast_tank_id;
	string direction;

	// Determine our fast tank id
	our_fast_tank_id = determine_our_tank_id(game_state, "TankFast");

	// Determine direction
	if (degrees > 0)
	{
		direction = "CW";
	}
	else
	{
		direction = "CCW";
		degrees = degrees * -1;
	}

	// Build a JSON command message
	json::Object obj; // Create a data container
	obj["tank_id"] = our_fast_tank_id;
	obj["comm_type"] = "ROTATE";
	obj["direction"] = direction;
	obj["rads"] = (degrees / 180)*3.14159265359;
	obj["client_token"] = client_token;
	string str = json::Serialize(obj); // Turn the container into a string

	// Send command
	send_command(command_channel, str);
	wait_for_response(command_channel);
}

void our_slow_tank_rotate(zmq::socket_t& command_channel, json::Object game_state, string client_token, double degrees)
{
	// Initialize variables
	string our_slow_tank_id;
	string direction;

	// Determine our slow tank id
	our_slow_tank_id = determine_our_tank_id(game_state, "TankSlow");

	// Determine direction
	if (degrees > 0)
	{
		direction = "CW";
	}
	else
	{
		direction = "CCW";
		degrees = degrees * -1;
	}

	// Build a JSON command message
	json::Object obj; // Create a data container
	obj["tank_id"] = our_slow_tank_id;
	obj["comm_type"] = "ROTATE";
	obj["direction"] = direction;
	obj["rads"] = (degrees / 180)*3.14159265359;
	obj["client_token"] = client_token;
	string str = json::Serialize(obj); // Turn the container into a string

	// Send command
	send_command(command_channel, str);
	wait_for_response(command_channel);
}

void our_fast_tank_rotate_turret(zmq::socket_t& command_channel, json::Object game_state, string client_token, double degrees)
{
	// Initialize variables
	string our_fast_tank_id;
	string direction;

	// Determine our fast tank id
	our_fast_tank_id = determine_our_tank_id(game_state, "TankFast");

	// Determine direction
	if (degrees > 0)
	{
		direction = "CW";
	}
	else
	{
		direction = "CCW";
		degrees = degrees * -1;
	}


	// Build a JSON command message
	json::Object obj; // Create a data container
	obj["tank_id"] = our_fast_tank_id;
	obj["comm_type"] = "ROTATE_TURRET";
	obj["direction"] = direction;
	obj["rads"] = (degrees / 180)*3.14159265359;
	obj["client_token"] = client_token;
	string str = json::Serialize(obj); // Turn the container into a string

	// Send command
	send_command(command_channel, str);
	wait_for_response(command_channel);
}

void our_slow_tank_rotate_turret(zmq::socket_t& command_channel, json::Object game_state, string client_token,double degrees)
{
	// Initialize variables
	string our_slow_tank_id;
	string direction;

	// Determine our slow tank id
	our_slow_tank_id = determine_our_tank_id(game_state, "TankSlow");

	// Determine direction
	if (degrees > 0)
	{
		direction = "CW";
	}
	else
	{
		direction = "CCW";
		degrees = degrees * -1;
	}

	// Build a JSON command message
	json::Object obj; // Create a data container
	obj["tank_id"] = our_slow_tank_id;
	obj["comm_type"] = "ROTATE_TURRET";
	obj["direction"] = direction;
	obj["rads"] = (degrees / 180)*3.14159265359;
	obj["client_token"] = client_token;
	string str = json::Serialize(obj); // Turn the container into a string

	// Send command
	send_command(command_channel, str);
	wait_for_response(command_channel);
}

void our_fast_tank_shoot(zmq::socket_t& command_channel, json::Object game_state, string client_token)
{
	// Initialize variables
	string our_fast_tank_id;

	// Determine our fast tank id
	our_fast_tank_id = determine_our_tank_id(game_state, "TankFast");

	// Build a JSON command message
	json::Object obj; // Create a data container
	obj["tank_id"] = our_fast_tank_id;
	obj["comm_type"] = "FIRE";
	obj["client_token"] = client_token;
	string str = json::Serialize(obj); // Turn the container into a string

	// Send command
	send_command(command_channel, str);
	wait_for_response(command_channel);
}

void our_slow_tank_shoot(zmq::socket_t& command_channel, json::Object game_state, string client_token)
{
	// Initialize variables
	string our_slow_tank_id;

	// Determine our slow tank id
	our_slow_tank_id = determine_our_tank_id(game_state, "TankSlow");

	// Build a JSON command message
	json::Object obj; // Create a data container
	obj["tank_id"] = our_slow_tank_id;
	obj["comm_type"] = "FIRE";
	obj["client_token"] = client_token;
	string str = json::Serialize(obj); // Turn the container into a string

	// Send command
	send_command(command_channel, str);
	wait_for_response(command_channel);
}

void our_fast_tank_stop(zmq::socket_t& command_channel, json::Object game_state, string client_token, string control)
{
	// Initialize variables
	string our_fast_tank_id;

	// Determine our slow tank id
	our_fast_tank_id = determine_our_tank_id(game_state, "TankFast");

	// Build a JSON command message
	json::Object obj; // Create a data container
	obj["tank_id"] = our_fast_tank_id;
	obj["comm_type"] = "STOP";
	obj["control"] = control;
	obj["client_token"] = client_token;
	string str = json::Serialize(obj); // Turn the container into a string

	// Send command
	send_command(command_channel, str);
	wait_for_response(command_channel);
}

void our_slow_tank_stop(zmq::socket_t& command_channel, json::Object game_state, string client_token, string control)
{
	// Initialize variables
	string our_slow_tank_id;

	// Determine our slow tank id
	our_slow_tank_id = determine_our_tank_id(game_state, "TankSlow");

	// Build a JSON command message
	json::Object obj; // Create a data container
	obj["tank_id"] = our_slow_tank_id;
	obj["comm_type"] = "STOP";
	obj["control"] = control;
	obj["client_token"] = client_token;
	string str = json::Serialize(obj); // Turn the container into a string

	// Send command
	send_command(command_channel, str);
	wait_for_response(command_channel);
}
